package guyubao.com.GreenLoong;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import guyubao.com.GreenLoong.entity.Environment;
import guyubao.com.GreenLoong.entity.Task;
import guyubao.com.utils.WebClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author wxa
 */
@Slf4j
@Component
public class GreenLoong {
    // 地址
    @Value("${green-loong.url}")
    public String URL;
    // 应用ID
    @Value("${green-loong.id}")
    public String ID = "9jA8MIeFYA-k";
    // 标识
    @Value("${green-loong.secretary}")
    public String SECRET = "paq4-9LW_4go_yWXplC4vS_W";
    // 登录成功后得到
    static private String token = "";
    // 身份
    static private String token_type = "";
    // 到期时间戳
    static private Long expiration = 0L;
    // 容器三十天会强制刷新token
    static private boolean thirtyDay = false;
    // 获取环境变量正常,不正常会重新登录，再获取失败就报错
    static private boolean evaState = true;
    
    static private Map<String, String> requestHeaders;
    
    // 环境变量所有信息
    public TreeMap<Integer, Environment> treeMap = new TreeMap<>();
    // 任务所有信息
    public HashMap<String, Task> taskMap = new HashMap<>();
    
    // 登录
    public String login() {
        try {
            if (thirtyDay || expiration <= System.currentTimeMillis() / 1000 - 3600) {
                token = "";
            }
            if (!token.isEmpty()) {
                return null;
            }
            String url = URL + "open/auth/token?client_id=" + ID + "&client_secret=" + SECRET;
            JSONObject jsonObject = WebClientUtils.sendParams(WebClientUtils.GET, url, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                return "连接至容器失败,状态码为：" + code;
            }
            JSONObject object = JSON.parseObject(jsonObject.getString("data"));
            token = object.getString("token");
            requestHeaders = new HashMap<>();
            requestHeaders.put("Authorization", "Bearer " + token);
            token_type = object.getString("token_type");
            expiration = object.getLong("expiration");
            System.out.println("登录成功,token为" + token + " 有效期至" + expiration);
            return null;
        } catch (Exception e) {
            return "连接至容器失败!" + e;
        }
    }
    
    // 获取所有环境变量
    public String getEnv() {
        String url = URL + "open/envs?searchValue=&t" + (System.currentTimeMillis() * 1000L);
        try {
            JSONObject jsonObject = WebClientUtils.sendParams(WebClientUtils.GET, url, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                return "容器获取环境变量失败->" + jsonObject.getJSONArray("message");
            }
            JSONArray data = jsonObject.getJSONArray("data");
            for (int i = 0; i < data.size(); i++) {
                JSONObject object = data.getJSONObject(i);
                // 索引 从1开始
                String id = object.getString("id");
                // 内容
                String value = object.getString("value");
                String timestamp = object.getString("timestamp");
                // 是否启用 0启用 1禁用
                String status = object.getString("status");
                String position = object.getString("position");
                // 名称
                String name = object.getString("name");
                // 备注
                String remarks = object.getString("remarks");
                // 创建时间 2023-09-11T02:53:31.806Z
                String createdAt = object.getString("createdAt");
                // 更新时间 2023-12-11T07:51:37.700Z
                String updatedAt = object.getString("updatedAt");
                treeMap.put(Integer.parseInt(id),
                        new Environment(id, value, timestamp, status, position, name, remarks, createdAt, updatedAt));
                evaState = true;
            }
            return null;
        } catch (Exception e) {
            // 可能是容器三十天强制刷新token,重新登录
            if (evaState) {
                evaState = false;
                thirtyDay = true;
                login();
                getEnv();
            } else {
                return "获取凭证变量失败!" + e;
            }
        }
        return null;
    }
    
    // 根据备注获得索引
    public int getIndex(String remarks) {
        if (remarks == null || remarks.isEmpty()) {
            System.out.println("remarks is null");
            return -1;
        }
        int index = 0;
        try {
            for (Environment environment : treeMap.values()) {
                if (environment.getRemarks().equals(remarks)) {
                    index = Integer.parseInt(environment.getId());
                    break;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return index;
    }
    
    // 更新环境变量
    public String updateEnv(String remarks, String value) {
        if (remarks == null || value == null || remarks.isEmpty() || value.isEmpty()) {
            return "更新环境变量,账号或值为空!";
        }
        String url = URL + "open/envs?t=" + (System.currentTimeMillis() * 1000L);
        try {
            int index = getIndex(remarks);
            if (index == 0) {
                return "没有找到该账号？";
            } else if (index == -1) {
                return "容器内该账号为空？";
            }
            JSONObject object = new JSONObject();
            object.put("name", "JD_COOKIE");
            object.put("value", value);
            object.put("remarks", remarks);
            object.put("id", index);
            JSONObject jsonObject = WebClientUtils.sendBody(WebClientUtils.PUT, url, object, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                return "更新环境变量失败->" + jsonObject.getJSONArray("message");
            }
            // 获得数据中的环境状态
            JSONObject object2 = JSON.parseObject(jsonObject.getString("data"));
            String status = object2.getString("status");
            // 如果环境被禁用就开启
            String s = null;
            if ("1".equals(status)) {
                s = startEnv(index);
            }
            return s;
        } catch (Exception e) {
            return "容器内部原因出错" + e;
        }
    }
    
    // 启用环境变量
    public String startEnv(int id) {
        if (id == 0) {
            return "启用环境变量,环境变量id不能为0!";
        }
        String url = URL + "open/envs/enable?t=" + (System.currentTimeMillis() * 1000L);
        try {
            JSONArray jsonArray = new JSONArray();
            jsonArray.add(id);
            JSONObject jsonObject = WebClientUtils.sendBody(WebClientUtils.PUT, url, jsonArray, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                return "启用环境变量失败->" + jsonObject.getJSONArray("message");
            }
            return null;
        } catch (Exception e) {
            return "服务内部出现问题！";
        }
    }
    
    // 增加环境变量
    public String addEnv(String remark, String value) {
        if (remark == null || value == null || remark.isEmpty() || value.isEmpty()) {
            return "增加环境变量,参数不正确!";
        }
        String url = URL + "open/envs?t=" + (System.currentTimeMillis() * 1000L);
        try {
            JSONArray jsonArray = new JSONArray();
            JSONObject object = new JSONObject();
            object.put("name", "JD_COOKIE");
            object.put("value", value);
            object.put("remarks", remark);
            jsonArray.add(object);
            System.out.println(jsonArray);
            JSONObject jsonObject = WebClientUtils.sendBody(WebClientUtils.POST, url, jsonArray, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                return "增加环境变量失败->" + jsonObject.getJSONArray("message");
            }
            return null;
        } catch (Exception e) {
            return "容器内部出错->" + e;
        }
    }
    
    // 获得所有任务信息
    public void getTask() {
        String encode = "";
        try {
            encode = URLEncoder.encode(
                    "searchValue=&page=1&size=500&filters={}&queryString={\"filters\":null,\"sorts\":null,\"filterRelation\":\"and\"}&t=",
                    "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage());
        }
        String url = URL + "/open/crons?" + encode + (System.currentTimeMillis() * 1000L);
        try {
            JSONObject jsonObject = WebClientUtils.sendParams(WebClientUtils.GET, url, requestHeaders);
            String code = jsonObject.getString("code");
            if (!"200".equals(code)) {
                System.out.println("获取所有任务信息失败");
                return;
            }
            JSONObject jsonObject2 = jsonObject.getJSONObject("data");
            JSONArray data = jsonObject2.getJSONArray("data");
            for (int i = 0; i < data.size(); i++) {
                JSONObject object = data.getJSONObject(i);
                String command = object.getString("command");
                String createdAt = object.getString("createdAt");
                int id = object.getIntValue("id");
                int isDisabled = object.getIntValue("isDisabled");
                int isPinned = object.getIntValue("isPinned");
                int isSystem = object.getIntValue("isSystem");
                JSONArray jsonArray = object.getJSONArray("labels");
                ArrayList<String> labels = new ArrayList<>();
                for (int j = 0; j < jsonArray.size(); j++) {
                    labels.add(jsonArray.getString(j));
                }
                long lastExecutionTime = Long.parseLong(object.getString("last_execution_time"));
                long lastRunningTime = Long.parseLong(object.getString("last_running_time"));
                String logPath = object.getString("log_path");
                String name = object.getString("name");
                String pid = object.getString("pid");
                boolean saved = object.getBoolean("saved");
                String schedule = object.getString("schedule");
                int status = Integer.parseInt(object.getString("status"));
                int subId = Integer.parseInt(object.getString("sub_id"));
                String timestamp = object.getString("timestamp");
                taskMap.put(name,
                        new Task(command, createdAt, id, isDisabled, isPinned, isSystem, labels, lastExecutionTime,
                                lastRunningTime, logPath, name, pid, saved, schedule, status, subId, timestamp));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
    
    // 运行指定的任务名称
    public void runTask(String name) {
        if (name == null || name.isEmpty()) {
            System.out.println("运行指定的任务id,没有任务名称!");
            return;
        }
        if (!taskMap.containsKey(name)) {
            System.out.println("运行指定的任务id,没有找到该任务!");
            return;
        }
        Task task = taskMap.get(name);
        JSONArray jsonArray = new JSONArray();
        int id = task.getId();
        jsonArray.add(id);
        String url = URL + "open/crons/run?t=" + (System.currentTimeMillis() * 1000L);
        try {
            JSONObject jsonObject = WebClientUtils.sendBody(WebClientUtils.PUT, url, jsonArray, requestHeaders);
            if (jsonObject.getInteger("code") != 200) {
                System.out.println(jsonObject.getString("message"));
                return;
            }
            System.out.println("运行指定的任务名称成功!");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
}
